package com.webex.ta.hydra.gui.wm;

import com.webex.ta.hydra.gui.GuiPackage;
import com.webex.ta.hydra.gui.HydraIdeFrame;
import com.webex.ta.hydra.gui.util.ThreeSplitPane;

import javax.swing.*;
import java.awt.*;
import java.awt.event.FocusEvent;

/**
 * Created by Cisco WebEx.
 * User: vegaz
 * Date: 2010-10-20
 * Time: 8:49:45
 */
public class ToolWindowPane extends JLayeredPane {
    private HydraIdeFrame frame;
    private ToolWindowManager manager;

    private SideBar topBar, leftBar, rightBar, bottomBar;
    private final ThreeSplitPane verticalSplit, horizontalSplit;


    public ToolWindowPane(final HydraIdeFrame frame, ToolWindowManager manager) {
        this.frame = frame;
        this.manager = manager;
        manager.setToolWindowPane(this);

        verticalSplit = new ThreeSplitPane(true);
        horizontalSplit = new ThreeSplitPane(false);
        verticalSplit.setInnerComponent(horizontalSplit);

        topBar = new SideBar(SwingConstants.TOP);
        leftBar = new SideBar(SwingConstants.LEFT);
        bottomBar = new SideBar(SwingConstants.BOTTOM);
        rightBar = new SideBar(SwingConstants.RIGHT);

        add(topBar, JLayeredPane.POPUP_LAYER);
        add(leftBar, JLayeredPane.POPUP_LAYER);
        add(bottomBar, JLayeredPane.POPUP_LAYER);
        add(rightBar, JLayeredPane.POPUP_LAYER);
        add(verticalSplit, JLayeredPane.DEFAULT_LAYER);
        this.setOpaque(true);
    }

    public void setDocumentComponent(JComponent c) {
        horizontalSplit.setInnerComponent(c);
        new FocusWatcher(c) {
            @Override
            protected void focusedComponentChanged(Component component) {
                ToolWindowManager.getInstance()._deactivateAllToolWindows();
            }

            @Override
            protected void focusLostImpl(FocusEvent e) {

            }
        };
    }

    @Override
    public void doLayout() {
        Dimension size = getSize();
        Dimension topSize = topBar.getPreferredSize();
        Dimension leftSize = leftBar.getPreferredSize();
        Dimension bottomSize = bottomBar.getPreferredSize();
        Dimension rightSize = rightBar.getPreferredSize();

        topBar.setBounds(0, 0, size.width, topSize.height);
        leftBar.setBounds(0, topSize.height, leftSize.width, size.height - topSize.height - bottomSize.height);
        rightBar.setBounds(size.width - rightSize.width, topSize.height, rightSize.width, size.height - topSize.height - bottomSize.height);
        bottomBar.setBounds(0, size.height - bottomSize.height, size.width, bottomSize.height);

        verticalSplit.setBounds(leftSize.width, topSize.height, size.width - leftSize.width - rightSize.width, size.height - topSize.height - bottomSize.height);
    }

    public void addSideBarButton(SideBarButton button) {
        switch (button.getAnchor()) {
            case SwingConstants.TOP:
                topBar.addButton(button);
                break;
            case SwingConstants.LEFT:
                leftBar.addButton(button);
                break;
            case SwingConstants.BOTTOM:
                bottomBar.addButton(button);
                break;
            case SwingConstants.RIGHT:
                rightBar.addButton(button);
                break;
        }
    }

    public void removeSideBarButton(SideBarButton button) {
        switch (button.getAnchor()) {
            case SwingConstants.TOP:
                topBar.removeButton(button);
                break;
            case SwingConstants.LEFT:
                leftBar.removeButton(button);
                break;
            case SwingConstants.BOTTOM:
                bottomBar.removeButton(button);
                break;
            case SwingConstants.RIGHT:
                rightBar.removeButton(button);
                break;
        }
    }

    public void addSlidingToolWindow(final InternalDecorator c) {
        int height = (int) (getHeight() * 0.33f + .5f);
        c.setBounds(0, getHeight() - height, getWidth(), height);
        verticalSplit.setLastComponent(c);
    }

    public void showFloatingToolWindow(final FloatingDecorator c) {
        WindowInfo info = c.getWindowInfo();
        Rectangle floatingBounds = info.getFloatingBounds();
        if (floatingBounds != null)
            c.setBounds(info.getFloatingBounds());
        else
            c.setLocationRelativeTo(GuiPackage.getInstance().getIdeFrame());
        c.setVisible(true);
    }

    public void showSlidingToolWindow(final InternalDecorator c) {
        WindowInfo info = c.getWindowInfo();
        float weight = info.getWeight();
        if (weight <= 0) {
            if (info.getAnchor() == SwingConstants.BOTTOM || info.getAnchor() == SwingConstants.TOP)
                weight = WindowInfo.DEFAULT_VERTICAL_WEIGHT;
            else
                weight = WindowInfo.DEFAULT_HORIZONTAL_WEIGHT;
        }
        switch (info.getAnchor()) {
            case SwingConstants.TOP:
                verticalSplit.setFirstComponent(c);
                verticalSplit.setFirstSize((int) (getHeight() * weight));
                break;
            case SwingConstants.LEFT:
                horizontalSplit.setFirstComponent(c);
                horizontalSplit.setFirstSize((int) (getWidth() * weight));
                break;
            case SwingConstants.BOTTOM:
                verticalSplit.setLastComponent(c);
                verticalSplit.setLastSize((int) (getHeight() * weight));
                break;
            case SwingConstants.RIGHT:
                horizontalSplit.setLastComponent(c);
                horizontalSplit.setLastSize((int) (getWidth() * weight));
                break;
        }
        this.revalidate();
    }

    public void hideFloatingToolWindow(final FloatingDecorator c) {
        c.setVisible(false);
    }

    public void hideSlidingToolWindow(final InternalDecorator c) {
        switch (c.getWindowInfo().getAnchor()) {
            case SwingConstants.TOP:
                verticalSplit.setFirstComponent(null);
                break;
            case SwingConstants.LEFT:
                horizontalSplit.setFirstComponent(null);
                break;
            case SwingConstants.BOTTOM:
                verticalSplit.setLastComponent(null);
                break;
            case SwingConstants.RIGHT:
                horizontalSplit.setLastComponent(null);
                break;
        }
        this.revalidate();
    }
}
